#-------------------------------------------------------------------------------
# Name:        exif1
#
# Author:      Dave
#
# Created:     04/12/2011
#-------------------------------------------------------------------------------
#!/usr/bin/env python

# Convert string of characters in reverse order to an integer number

import sys
import os, fnmatch



def exif_number(s):
    n = 0
    digit_count = 0
    multiplier = 1
    for c in s:
        n += multiplier * ord(c)
        multiplier = multiplier * 256
    return n

# Convert attribute number to name
def get_attribute_name(attribute_number):
    exif_tags = {
        270     :   "ImageDescription",
        271     :   "Make",
        272     :   "Model",
        274     :   "Orientation",
        282     :   "XResolution",
        283     :   "YResolution",
        296     :   "ResolutionUnit",
        305     :   "Software",
        306     :   "DateTime",
        531     :   "YCbCrPositioning",
        34665   :   "ExitIDF"
        }
    for num, name in exif_tags.iteritems():
        if num == attribute_number:
            return name
    return "Unknown" + str(num)


def find_files(directory, pattern):
    for root, dirs, files in os.walk(directory):
        for basename in files:
            if fnmatch.fnmatch(basename, pattern):
                filename = os.path.join(root, basename)
                yield filename


for filename in find_files('src', '*.c'):
    print 'Found C source:', filename


def process_exif(ofn,filename):
    jpg_dir = os.path.dirname(filename)
    jpg_name = os.path.basename(filename)[:-4]
    with open(filename, 'rb') as f:
        str = ""
        i = 0
        tiff_offset = 0
        attribute_number = 0
        attribute_name = ""
        attribute_count = 0
        make = ""
        model = ""
        date_time = ""
        while tiff_offset == 0 and i < 50:
            f.seek(i)
            x = f.read(1)
            a = ("0"+((hex(ord(x)))[2:]))[-2:]
            str = str + a
            if str[-4:] == '4949':
                tiff_offset = i+9
            else:
                i += 1
        if tiff_offset == 0:
            ofn.write("\"" + jpg_name + "\" File data not recognised\n")
        else:
            while attribute_name != "ExitIDF":
                i = tiff_offset + (attribute_count * 12)
                f.seek(i)
                attribute_number = exif_number(f.read(2))
                attribute_name = get_attribute_name(attribute_number)
                if attribute_name != "ExitIDF":
                    attribute_type = exif_number(f.read(2))
                    attribute_length = exif_number(f.read(4))
                    attribute_offset = exif_number(f.read(4))
                    attribute_pointer = attribute_offset + tiff_offset - 10
                    if attribute_type == 3:  # SHORT
                        attribute_value = attribute_offset
                    elif attribute_type == 4:  # LONG
                        attribute_value = attribute_offset
                    elif attribute_type == 9:  # SLONG
                        attribute_value = attribute_offset
                        # allow for signed number
                    else:
                        f.seek(attribute_pointer)
                        if attribute_type == 1:  # BYTE
                            attribute_value = f.read(1)
                        elif attribute_type == 2:  # ASCII
                            attribute_value = f.read(attribute_length - 1)
                        elif attribute_type == 4:  # LONG
                            attribute_value = exif_number(f.read(4))
                        elif attribute_type == 5:  # RATIONAL
                            attribute_value = exif_number(f.read(4)) / exif_number(f.read(4))
                        elif attribute_type == 7:  # UNDEFINED
                            attribute_value = f.read(1)
                        elif attribute_type == 9:  # SLONG
                            attribute_value = exif_number(f.read(4))
                            # allow for signed number
                        elif attribute_type == 10:  # SRATIONAL
                            attribute_value = exif_number(f.read(4)) / exif_number(f.read(4))
                            # allow for signed number
                    if attribute_name == "Make":
                        make = attribute_value
                    elif attribute_name == "Model":
                        model = attribute_value
                    elif attribute_name == "DateTime":
                        date_time = attribute_value
                    attribute_count += 1
            print jpg_name
            ofn.write("  <exif path=\"" + jpg_dir + "\" name=\"" + jpg_name + "\" make=\"" + make + "\" model=\"" + model + "\" date_time=\"" + date_time + "\" />\n")

def main():
    ofn = open('exifdata.xml', 'w')
    ofn.write("<exifs>\n")
    base_path = ".\\"
    file_scope = "*"
    if len(sys.argv) > 1:
        file_scope = sys.argv[1]
        if len(sys.argv) > 2:
            base_path = sys.argv[2]
    file_scope += ".jpg"
    for filename in find_files(base_path, file_scope):
        process_exif(ofn,filename)
    ofn.write("  </exifs>\r\n")
    ofn.close

if __name__ == '__main__':
    main()